﻿using CommonlyUtils;
using ImClientApi.Utils;
using ImModels.Service.Models.Data;
using ImModels.View;
using ImModels.View.MsgJson;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using xl.webapi.db_helper_interface;

namespace ImClientApi.Controllers
{
    /// <summary>
    /// 我的会话列表 管理控制器接口相关
    /// </summary>
    public class MySessionController : BaseAuthController
    {
        /// <summary>
        /// 获取会话列表
        /// </summary>
        /// <param name="reqview">data为 业务测的 用户唯一ID 会鉴权使用的</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ResView<List<MySession>>> GetList([FromBody] ReqView<string> reqview)
        {
            var jwtUser = GetUseByJwtToken();

            if (jwtUser.BizUserID != reqview.Data || jwtUser.EnterpriseId != reqview.AppId.ToString())
            {
                return await ReturnFailed(302, "当前Token和登录用户信息不匹配，请核对修改后重试");
            }

            var itemsDb = await DbUtils.DbHelper.GetListPageAsync<MySession>(p => p.EnterpriseId == reqview.AppId && p.BizUserId == reqview.Data && p.SessionId > reqview.Cursor, 1, reqview.PageSize, p => p.IsTop, OrderType.Desc);

            //所有接受用户的Db数据
            var toUserUserDbIds = itemsDb.Where(p => p.IsGroup == 0).Select(p => p.ToUserId);
            var allUsersDb = await DbUtils.DbHelper.GetListAsync<Users>(p => toUserUserDbIds.Contains(p.BizUserId) && p.EnterpriseId == reqview.AppId);

            foreach (var item in itemsDb)
            {
                if (item.IsGroup == 0)
                {
                    var user = allUsersDb.FirstOrDefault(p => p.BizUserId == item.ToUserId);
                    item.FullName = user?.FullName ?? item.FullName;
                }
            }

            var groupIds = itemsDb.Where(p => p.IsGroup == 1).Select(p => Convert.ToInt64(p.ToUserId));
            var allGroupUserDb = await DbUtils.DbHelper.GetListAsync<ImGroupUser>(p => groupIds.Contains(p.GroupId));
            var allGroupDb = await DbUtils.DbHelper.GetListAsync<ImGroups>(p => groupIds.Contains(p.KID));
            foreach (var item in itemsDb)
            {
                if (item.IsGroup == 1)
                {
                    var tmp = allGroupDb.FirstOrDefault(p => p.KID == Convert.ToInt64(item.ToUserId));
                    item.FullName = tmp?.FullName ?? item.FullName;

                    item.GroupUser = allGroupUserDb.Where(p => p.GroupId == Convert.ToInt64(item.ToUserId)).ToList();
                }
            }

            return new ResView<List<MySession>>() { code = 200, msg = "成功", data = itemsDb };
        }

        /// <summary>
        /// 创建一个会话，创建成功之后返回会话Id，会话头像 名称之类的
        /// 有 2 种方式 创建会话
        /// 1.点击通讯录里面的用户,比如右键选人之后  发消息,这个时候没有会话ID,则需要传 通讯录用户相关的信息 IM自动创建会话
        /// 2.已有群里 点击群聊里面的其中一个群友 进入
        /// </summary>
        /// <param name="reqview"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ResView<MySession>> Create([FromBody] ReqView<CreateSessionReq> reqview)
        {
            var jwtUser = GetUseByJwtToken();

            if (jwtUser.BizUserID != reqview.Data.BizUserId || jwtUser.EnterpriseId != reqview.AppId.ToString())
            {
                return await ReturnFailed(302, "当前Token和登录用户信息不匹配，请核对修改后重试");
            }

            if (string.IsNullOrWhiteSpace(reqview.Data.ToUserId))
            {
                return new ResView<MySession>() { code = 500, msg = "接收方用户ID不能为空，请修改后重试" };
            }

            //发送方的会话
            #region 是否存在会话，不存在则加一个
            var sessionId = Builder.GetNewSnowId();
            var sendSessionDb = await DbUtils.DbHelper.GetOneAsync<MySession>(p => p.EnterpriseId == reqview.AppId
                       && p.BizUserId == reqview.Data.BizUserId
                       && p.ToUserId == reqview.Data.ToUserId && p.IsGroup == 0);
            if (sendSessionDb == null || sendSessionDb.SessionId == 0)
            {
                //1 添加自己的会话
                var addDb = await DbUtils.DbHelper.AddItemAsync<MySession>(new MySession()
                {
                    SessionId = sessionId,
                    EnterpriseId = reqview.AppId,
                    BizUserId = reqview.Data.BizUserId,
                    ToUserId = reqview.Data.ToUserId,
                    IsGroup = 0,
                    FullName = reqview.Data.ToUserName,
                    HeadImg = reqview.Data.HeadImg
                });
                if (addDb == 0)
                {
                    return new ResView<MySession>() { code = 500, msg = "会话创建失败，请稍后重试" };
                }
                sendSessionDb = await DbUtils.DbHelper.GetOneAsync<MySession>(p => p.SessionId == sessionId);
            }
            #endregion

            #region 是否存在好友 用户  不存在加 一个
            //2 添加用户
            var toUserDb = await DbUtils.DbHelper.GetOneAsync<Users>(p => p.BizUserId == reqview.Data.ToUserId);
            if (toUserDb == null || toUserDb.KID == 0)
            {
                var addDb = await DbUtils.DbHelper.AddItemAsync<Users>(new Users()
                {
                    KID = Builder.GetNewSnowId(),
                    EnterpriseId = reqview.AppId,
                    JobName = reqview.Data.ToUserJob,
                    BizUserId = reqview.Data.ToUserId,
                    FullName = reqview.Data.ToUserName,
                    HeadImg = reqview.Data.HeadImg,
                    ContactTel = reqview.Data.ToUserTel
                });
                if (addDb == 0)
                {
                    return new ResView<MySession>() { code = 500, msg = "接收方创建失败，请稍后重试" };
                }
            }
            #endregion

            #region 接收方的会话 交换发送方 接受方
            var toUserSessionDb = await DbUtils.DbHelper.GetOneAsync<MySession>(p => p.EnterpriseId == reqview.AppId
                        && p.BizUserId == reqview.Data.ToUserId
                        && p.ToUserId == jwtUser.BizUserID && p.IsGroup == 0);
            if (toUserSessionDb == null || toUserSessionDb.SessionId == 0)
            {
                var sendUserDb = await DbUtils.DbHelper.GetOneAsync<Users>(p => p.BizUserId == reqview.Data.BizUserId);
                //1 添加好友的会话
                var addDb = await DbUtils.DbHelper.AddItemAsync<MySession>(new MySession()
                {
                    SessionId = sessionId,
                    EnterpriseId = reqview.AppId,
                    BizUserId = reqview.Data.ToUserId,
                    ToUserId = reqview.Data.BizUserId,
                    IsGroup = 0,
                    FullName = sendUserDb.FullName,
                    HeadImg = sendUserDb.HeadImg
                });
                if (addDb == 0)
                {
                    return new ResView<MySession>() { code = 500, msg = "会话创建失败，请稍后重试" };
                }

                toUserSessionDb = await DbUtils.DbHelper.GetOneAsync<MySession>(p => p.EnterpriseId == reqview.AppId
                        && p.ToUserId == reqview.Data.BizUserId
                        && p.BizUserId == reqview.Data.ToUserId && p.IsGroup == 0);

                var chat_Session = new Msg_Session()
                {
                    sessionid = sessionId,
                    session = new SessionItem()
                    {
                        flags = toUserSessionDb.Flags,
                        fullname = toUserSessionDb.FullName,
                        headimg = toUserSessionDb.HeadImg,
                        isgroup = toUserSessionDb.IsGroup,
                        toUserId = toUserSessionDb.ToUserId
                    }
                };

                //给接收方 发一个新建会话的消息
                await ImMsgLogic.SendSessionMsg(chat_Session, new List<string> { reqview.Data.ToUserId }, Convert.ToInt64(jwtUser.UserKid));
            }
            #endregion

            return new ResView<MySession>() { code = 200, msg = "ok", data = sendSessionDb };
        }


        /// <summary>
        /// 打开一个会话信息 进入聊天框 data为 session 会话ID
        /// 可以异步，先打开，再查询
        /// 接口会判断是 私聊 还是 群聊，会判断群是否被删除和更新群相关信息
        /// </summary>
        /// <param name="reqview"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ResView<OpenSessionRes>> Open([FromBody] ReqView<DelSessionView> reqview)
        {
            var jwtUser = GetUseByJwtToken();

            if (jwtUser.EnterpriseId != reqview.AppId.ToString())
            {
                return await ReturnFailed(302, "当前Token和登录用户信息不匹配，请核对修改后重试");
            }

            var sessionId = reqview.Data.SessionId;
            if (sessionId <= 0)
            {
                return new ResView<OpenSessionRes>() { code = 300, msg = "会话ID不能为空" };
            }

            var itemDb = await DbUtils.DbHelper.GetOneAsync<MySession>(p => p.SessionId == sessionId && p.BizUserId == jwtUser.BizUserID);
            if (itemDb == null || itemDb.SessionId == 0 || itemDb.IsDeleted == 1)
            {
                return new ResView<OpenSessionRes>() { code = 404, msg = "当前会话已被删除" };
            }

            var resData = new OpenSessionRes()
            {
                IsGroup = itemDb.IsGroup,
                ToBizUserId = itemDb.ToUserId,
                FullName = itemDb.FullName,
                NickName = itemDb.NickName,
                HeadImg = itemDb.HeadImg,
                ExJson = itemDb.ExJson
            };
            if (itemDb.IsGroup == 1)
            {
                var groupId = Convert.ToInt64(itemDb.ToUserId);
                var imGroupDb = await DbUtils.DbHelper.GetOneAsync<ImGroups>(p => p.KID == groupId && p.IsDeleted == 0);
                if (imGroupDb == null || imGroupDb.KID == 0 || imGroupDb.IsDeleted == 1)
                {
                    return new ResView<OpenSessionRes>() { code = 404, msg = "当前群聊已被删除" };
                }
                resData.FullName = imGroupDb.FullName;
                resData.HeadImg = imGroupDb.HeadImg;
                resData.ExJson = imGroupDb.ExJson;

                ///获取所有未删除的数据
                var imGroupUsersDb = await DbUtils.DbHelper.LeftJoinAsync<ImGroupUser, Users, ImGroupUser>((a, b) => a.BizUserId == b.BizUserId && a.EnterpriseId == b.EnterpriseId,
                    (a, b) => a.GroupId == groupId && b.IsDeleted == 0, a => a.KID, OrderType.Asc, (a, b) => new ImGroupUser()
                    {
                        KID = a.KID,
                        FullName = b.FullName,
                        BizUserId = a.BizUserId,
                        EnableTime = a.EnableTime,
                        EnterpriseId = a.EnterpriseId,
                        GroupId = a.GroupId,
                        InviterBizUserId = a.InviterBizUserId,
                        JoinComment = a.JoinComment,
                        JoinState = a.JoinState,
                        JoinTime = a.JoinTime
                    });

                resData.GroupUsers = imGroupUsersDb;
            }

            var msgDbItems = new List<Msgs>();
            if (itemDb.IsGroup == 2)
            {
                //查询msg消息 系统回话 或者 自己发的消息
                msgDbItems = await DbUtils.DbHelper.GetListPageAsync<Msgs>(p => p.KID > reqview.Cursor && p.SessionId == reqview.AppId && (p.ToBizUserId == jwtUser.BizUserID || p.ToBizUserId == "0" || p.FromBizUserId == jwtUser.BizUserID), 1, reqview.PageSize, p => p.KID, xl.webapi.db_helper_interface.OrderType.Desc);
            }
            else if (itemDb.IsGroup == 0)
            {
                #region 私聊消息
                msgDbItems = await DbUtils.DbHelper.GetListPageAsync<Msgs>(p => p.KID > reqview.Cursor && p.SessionId == reqview.Data.SessionId, 1, reqview.PageSize, p => p.KID, xl.webapi.db_helper_interface.OrderType.Desc);
                #endregion
            }
            else
            {
                //查询群消息 msg消息
                msgDbItems = await DbUtils.DbHelper.GetListPageAsync<Msgs>(p => p.KID > reqview.Cursor && p.SessionId == reqview.Data.SessionId, 1, reqview.PageSize, p => p.KID, xl.webapi.db_helper_interface.OrderType.Desc);
            }

            resData.ChatMsgs = msgDbItems;

            return new ResView<OpenSessionRes>() { code = 200, msg = "获取成功", data = resData };
        }

        /// <summary>
        /// 删除一个会话
        /// </summary>
        /// <param name="reqview"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ResView> Del([FromBody] ReqView<DelSessionView> reqview)
        {
            var jwtUser = GetUseByJwtToken();

            if (jwtUser.EnterpriseId != reqview.AppId.ToString())
            {
                return await ReturnFailed(302, "当前Token和登录用户信息不匹配，请核对修改后重试");
            }

            if (reqview.Data.SessionId == 0)
            {
                return new ResView() { code = 500, msg = "删除失败，会话ID不能为空" };
            }

            var delDb = await DbUtils.DbHelper.DeleteItemAsync<MySession>(p => p.SessionId == reqview.Data.SessionId && p.BizUserId == jwtUser.BizUserID);

            return new ResView() { code = delDb > 0 ? 200 : 500, msg = "删除" + (delDb > 0 ? "成功" : "失败") };
        }
    }
}
